package com.himiotech.core.project.web.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.himiotech.core.framework.helper.anno.Log;
import com.himiotech.core.framework.helper.constant.UserConstants;
import com.himiotech.core.framework.helper.enums.BusinessType;
import com.himiotech.core.framework.helper.utils.ExcelUtil;
import com.himiotech.core.framework.helper.utils.ShiroUtils;
import com.himiotech.core.project.model.entity.role.Role;
import com.himiotech.core.project.model.entity.user.User;
import com.himiotech.core.project.model.metadata.UserMetadata;
import com.himiotech.core.project.service.IPostService;
import com.himiotech.core.project.service.IRoleService;
import com.himiotech.core.project.service.IUserService;
import com.himiotech.core.project.web.base.HimioBaseController;
import com.himiotech.core.project.web.base.model.HimioResult;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户信息
 *
 * @author ruoyi
 * @author wuwenbin
 */
@Controller
@RequestMapping("/system/user")
public class UserController extends HimioBaseController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IPostService postService;

    @RequiresPermissions("system:user:view")
    @GetMapping()
    public String user(ModelMap mmp) {
        mmp.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        mmp.put("posts", postService.list());
        return "system/deptUser";
    }

    @RequiresPermissions("system:user:list")
    @PostMapping("/list")
    @ResponseBody
    public HimioResult list(Page<User> userPage, User user) {
        handleOrderBy(request, userPage);
        Page<User> result = userService.selectUserListPage(userPage, user);
        return writeJsonLayuiTable(result);
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:user:export")
    @PostMapping("/export")
    @ResponseBody
    public HimioResult export(User user) {
        QueryWrapper<User> query = Wrappers.query();
        if (user != null) {
            query.eq(UserMetadata.DEL_FLAG.getColName(), 0)
                    .like(StringUtils.isNotEmpty(user.getLoginName()), UserMetadata.LOGIN_NAME.getColName(), user.getLoginName())
                    .like(StringUtils.isNotEmpty(user.getPhoneNumber()), UserMetadata.PHONE_NUMBER.getColName(), user.getPhoneNumber())
                    .eq(StringUtils.isNotEmpty(user.getStatus()), UserMetadata.STATUS.getColName(), user.getStatus())
                    .ge(ObjectUtils.isNotEmpty(user.getSearchParams().get("gmtCreateStart")), UserMetadata.GMT_CREATE.getColName(), user.getSearchParams().get("gmtCreateStart"))
                    .le(ObjectUtils.isNotEmpty(user.getSearchParams().get("gmtCreateEnd")), UserMetadata.GMT_CREATE.getColName(), user.getSearchParams().get("gmtCreateEnd"));
        }
        List<User> result = userService.list(query);
        ExcelUtil<User> util = new ExcelUtil<>(User.class);
        return util.exportExcel(result, "用户数据");
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @RequiresPermissions("system:user:import")
    @PostMapping("/importData")
    @ResponseBody
    public HimioResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<User> util = new ExcelUtil<>(User.class);
        List<User> userList = util.importExcel(file.getInputStream());
        String message = userService.importUser(userList, updateSupport);
        return writeJsonOk(message);
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/importTemplate")
    @ResponseBody
    public HimioResult importTemplate() {
        ExcelUtil<User> util = new ExcelUtil<>(User.class);
        return util.importTemplateExcel("用户数据");
    }

    /**
     * 新增保存用户
     */
    @RequiresPermissions("system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public HimioResult addSave(@Validated User user) {
        if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName()))) {
            return writeJsonErr("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return writeJsonErr("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return writeJsonErr("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        return writeJson(userService.insertUser(user));
    }

    /**
     * 修改保存用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public HimioResult editSave(@Validated User user) {
        userService.checkUserAllowed(user);
        if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return writeJsonErr("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return writeJsonErr("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setPassword(null);
        return writeJson(userService.updateUser(user));
    }

    @RequiresPermissions("system:user:edit")
    @GetMapping("/editUserExtraInfo")
    @ResponseBody
    public Object editUserExtraInfo(Long userId) {
        Map<String, Object> result = new HashMap<>(2);
        List<Role> roles = roleService.selectRolesByUserId(userId);
        result.put("roles", User.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        result.put("posts", postService.selectPostsByUserId(userId));
        return result;
    }


    @RequiresPermissions("system:user:resetPwd")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    @ResponseBody
    public HimioResult resetPwdSave(User user) {
        userService.checkUserAllowed(user);
        if (userService.resetUserPwd(user) > 0) {
            if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue()) {
                setSysUser(userService.getById(user.getUserId()));
            }
            return writeJsonOk();
        }
        return writeJsonErr();
    }


    /**
     * 用户授权角色
     */
    @RequiresPermissions("system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PostMapping("/authRole/insertAuthRole")
    @ResponseBody
    public HimioResult insertAuthRole(Long userId, Long[] roleIds) {
        userService.insertUserAuth(userId, roleIds);
        return writeJsonOk();
    }

    @RequiresPermissions("system:user:remove")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public HimioResult remove(String ids) {
        return writeJson(userService.deleteUserByIds(ids));
    }

    /**
     * 校验用户名
     */
    @PostMapping("/checkLoginNameUnique")
    @ResponseBody
    public String checkLoginNameUnique(User user) {
        return userService.checkLoginNameUnique(user.getLoginName());
    }

    /**
     * 校验手机号码
     */
    @PostMapping("/checkPhoneUnique")
    @ResponseBody
    public String checkPhoneUnique(User user) {
        return userService.checkPhoneUnique(user);
    }

    /**
     * 校验email邮箱
     */
    @PostMapping("/checkEmailUnique")
    @ResponseBody
    public String checkEmailUnique(User user) {
        return userService.checkEmailUnique(user);
    }

    /**
     * 用户状态修改
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @RequiresPermissions("system:user:edit")
    @PostMapping("/changeStatus")
    @ResponseBody
    public HimioResult changeStatus(User user) {
        userService.checkUserAllowed(user);
        return writeJson(userService.updateById(user));
    }
}